use super::*;
use indicatif::{ProgressBar, ProgressStyle};
use std::fs::{create_dir_all, File};
use std::io;
use std::path::Path;
use std::time::Duration;

pub struct ScreenshotCmd<P>
where
  P: AsRef<Path>,
{
  out: P,
}

impl<P> ScreenshotCmd<P>
where
  P: AsRef<Path>,
{
  pub fn new(out: P) -> Self {
    return ScreenshotCmd { out };
  }
}

impl<P> BinaryCommand for ScreenshotCmd<P>
where
  P: AsRef<Path>,
{
  type Output = io::Result<bool>;
  fn exec(&self) -> Self::Output {
    if cfg!(target_os = "windows") {
      panic!("no impl for windows!")
    } else {
      let png = File::create(self.out.as_ref())?;
      let mut cmd = Command::new(ADB_BIN)
        .arg("exec-out")
        .arg("screencap")
        .arg("-p")
        .stdout(png)
        .spawn()?;

      cmd.wait()?;
      Ok(true)
    }
  }
}

pub struct ScreenshotCmdEx<'a, P>
where
  P: AsRef<Path>,
{
  pkg: &'a str,
  num: usize,
  out_dir: P,
}

impl<'a, P> ScreenshotCmdEx<'a, P>
where
  P: AsRef<Path>,
{
  pub fn new(pkg: &'a str, num: usize, out_dir: P) -> Self {
    return ScreenshotCmdEx { pkg, num, out_dir };
  }
  fn ensure_out_dir(&self) -> io::Result<()> {
    create_dir_all(self.out_dir.as_ref())
  }
  fn screencap<S>(&self, out: S) -> io::Result<bool>
  where
    S: AsRef<Path>,
  {
    let png = File::create(out)?;
    let mut cmd = Command::new(ADB_BIN)
      .arg("exec-out")
      .arg("screencap")
      .arg("-p")
      .stdout(png)
      .spawn()?;

    cmd.wait()?;
    Ok(true)
  }
}

impl<'a, P> BinaryCommand for ScreenshotCmdEx<'a, P>
where
  P: AsRef<Path>,
{
  type Output = io::Result<bool>;
  fn exec(&self) -> Self::Output {
    if cfg!(target_os = "windows") {
      panic!("no impl for windows!")
    } else {
      super::start_app(self.pkg)?;
      self.ensure_out_dir()?;
      let mut success = true;

      let pb = ProgressBar::new_spinner();
      pb.enable_steady_tick(Duration::from_millis(120));
      // let pb = ProgressBar::new(self.num as u64);
      pb.set_style(
        ProgressStyle::with_template("{spinner:.blue} {msg}")
          .unwrap()
          // For more spinners check out the cli-spinners project:
          // https://github.com/sindresorhus/cli-spinners/blob/master/spinners.json
          .tick_strings(&[
            "▹▹▹▹▹",
            "▸▹▹▹▹",
            "▹▸▹▹▹",
            "▹▹▸▹▹",
            "▹▹▹▸▹",
            "▹▹▹▹▸",
            "▪▪▪▪▪",
          ]),
      );

      for i in 0..self.num {
        pb.set_message(format!("截图{}/{}...", i + 1, self.num));
        // 滚动
        ShellCmd::new(
          &["input swipe 0 1100 0 100"],
          Some(Box::new(|_| String::from(""))),
        )
        .exec()?;

        // // 截屏
        let out = format!("{}/{}.png", self.out_dir.as_ref().display(), i);
        success = success && self.screencap(&out)?;
        if success {
          super::image::binarization_image(&out, None)?;
        } else {
          pb.abandon_with_message("screencap fail!");
          return Err(io::Error::new(io::ErrorKind::Other, "screencap fail"));
        }

        // pb.inc(1);
        // thread::sleep(Duration::from_millis(5));
      }
      // pb.finish_and_clear();

      pb.finish_with_message("Done");
      Ok(success)
    }
  }
}
